package com.snopy.lambda;

import com.snopy.pojo.Person;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 * @author snopy
 * @version 1.0.0
 * @classname RosterTest
 * @description potentially
 * @email 77912204@qq.com
 * @date 2022/07/22 10:50
 */
public class RosterTest {
    interface CheckPerson{
        boolean test(Person p);
    }

    // Approach 2 older than specified age
    public static void printPersonOlderThan(List<Person> roster,int age){
        for (Person p:roster) {
            if (p.getAge() > age){
                p.printPerson();
            }
        }
    }
    //Approach 2
    public static void printPersonWithinAgeRange(List<Person> roster,int low,int high){
        for (Person p:roster) {
            if (p.getAge() >= low && p.getAge() < high){
                p.printPerson();
            }
        }
    }

    public static void printPersons(List<Person> roster,CheckPerson tester){
        for (Person p:roster) {
            if (tester.test(p)){
                p.printPerson();
            }
        }
    }
    public static void printPersonsWithPredicate(List<Person> roster, Predicate<Person> tester){
        for (Person p:roster) {
            if (tester.test(p)){
                p.printPerson();
            }
        }
    }
    public static void processPersons(List<Person> roster, Predicate<Person> tester, Consumer<Person> c){
        for (Person p:roster) {
            if (tester.test(p)){
                c.accept(p);
            }
        }
    }
    public static void processPersonsWithFunctions(List<Person> roster,
                                                   Predicate<Person> tester,
                                                   Function<Person,String> mapper,
                                                   Consumer<String> block){
        for (Person p:roster) {
            if (tester.test(p)){
                String data = mapper.apply(p);
                block.accept(data);
            }
        }
    }
    public static <X,Y> void processElements(List<X> roster,
                                             Predicate<X> tester,
                                             Function<X,Y> mapper,
                                             Consumer<Y> block){
        for (X x:roster) {
            if (tester.test(x)){
                Y apply = mapper.apply(x);
                block.accept(apply);
            }
        }
    }
    public static void main(String[] args) {
        List<Person> roster = Person.createPerson(200);

        printPersonOlderThan(roster,40);
        System.out.println("-----------------------------------------");
        printPersonWithinAgeRange(roster,10,30);
        class DefaultCheckPerson implements CheckPerson{
            @Override
            public boolean test(Person p) {
                return p.getGender() == Person.Sex.FEMALE
                        &&p.getAge()>=18
                        &&p.getAge()<=25;
            }
        }
        System.out.println("-----------------------------------------");
        printPersons(roster,new DefaultCheckPerson());
        System.out.println("--------------------anonymous class---------------------");
        printPersons(roster,new CheckPerson(){
            @Override
            public boolean test(Person p) {
                return p.getGender() == Person.Sex.FEMALE
                        &&p.getAge()>=18
                        &&p.getAge()<=25;
            }
        });
        System.out.println("--------------------lambda expression---------------------");
        printPersons(roster,p -> p.getGender()== Person.Sex.FEMALE
                                 &&p.getAge()>=18&&p.getAge()<=25);

        System.out.println("---------------------------predicate----------------------------");
        printPersonsWithPredicate(roster,person -> person.getGender()== Person.Sex.FEMALE
                                        && person.getAge()>=18&& person.getAge()<=25);
        System.out.println("------------------------use lambda expressions "+"throught your app---------------------");
        processPersons(roster,p->p.getGender()== Person.Sex.FEMALE&&p.getAge()>=18&&p.getAge()<=25,p->p.printPerson());
        System.out.println("------------------------use lambda expressions "+"throught your app---------------------");
        processPersons(roster,p->p.getGender()== Person.Sex.FEMALE&&p.getAge()>=18&&p.getAge()<=25,Person::printPerson);
        System.out.println("-------------------------use lambda " +
                "exporessions second example---------------------------------------------------");
        processPersonsWithFunctions(roster,p-> p.getGender() == Person.Sex.MALE&&p.getAge()>=18&&p.getAge()<=25,
                p->p.getEmailAddress(), email-> System.out.println(email));

        System.out.println("-------------------------Use Generics More Extensively---------------------------");
        processElements(roster,p->p.getGender() == Person.Sex.FEMALE&&p.getAge()>=18&&p.getAge()<=25,
                p->p.getEmailAddress(),p-> System.out.println(p));
        processElements(roster,p->p.getGender() == Person.Sex.FEMALE&&p.getAge()>=18&&p.getAge()<=25,
                Person::getEmailAddress, System.out::println);

        System.out.println("------------------Use Bulk Data " + "Operations That Accept Lambda Expressions----------");
        roster
              .stream()
              .filter(p->p.getGender() == Person.Sex.FEMALE && p.getAge()>=18 && p.getAge()<=25)
              .map(p->p.getEmailAddress())
              .forEach(p-> System.out.println(p));


    }


}
